/**
 * $Revision: 1.0 $
 * $Author: Geln Yang $
 * $Date: May 19, 2010 10:32:40 PM $
 *
 * Author: Geln Yang
 * Date  : May 19, 2010 10:32:40 PM
 *
 */
package com.gooex.service.schedual.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.c4j.freemarker.FreemarkerTools;
import org.c4j.mail.SpringMailSender;
import org.c4j.string.StringTools;
import org.c4j.system.web.hibernate.BaseHibernateService;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import com.gooex.domain.common.Subscription;
import com.gooex.service.schedual.ISubscriptionManager;

import freemarker.template.TemplateException;

/**
 * @author Geln Yang
 * @version 1.0
 */
public class SubscriptionManagerImpl extends BaseHibernateService implements ISubscriptionManager {

	private SpringMailSender mailSender;

	private Map<String, String> templates = new HashMap<String, String>();

	public void savaOrUpdate(Subscription subscription) {
		getHibernateTemplate().saveOrUpdate(subscription);
	}

	public void remove(Subscription subscription) {
		getHibernateTemplate().delete(subscription);
	}

	public Subscription getSubscription(String email, String category) {
		String hql = "from " + Subscription.class.getName() + " where email=? and category=?";
		List<Subscription> result = findHQLQuery(hql, new Object[] { email, category }, null);
		if (result != null && result.size() > 0)
			return result.get(0);
		return null;
	}

	public List<Subscription> getSubscriptionsByCategory(String category) {
		String hql = "from " + Subscription.class.getName() + " where category=? order by interval";
		return findHQLQuery(hql, new Object[] { category }, null);
	}

	public List<Subscription> getConfirmedSubscriptions(String category, String[] intervals) {
		Criteria criteria = getSession().createCriteria(Subscription.class);
		criteria = criteria.add(Restrictions.eq("category", category));
		criteria = criteria.add(Restrictions.in("interval", intervals));
		return criteria.list();
	}

	public List<Subscription> getSubscriptionsByEmail(String email) {
		String hql = "from " + Subscription.class.getName() + " where email=? order by category,interval";
		return findHQLQuery(hql, new Object[] { email }, null);
	}

	public List<Subscription> getSubscriptionsByInterval(String interval) {
		String hql = "from " + Subscription.class.getName() + " where interval=? order by category";
		return findHQLQuery(hql, new Object[] { interval }, null);
	}

	public Subscription create(String email, String category, String interval) {
		Subscription subscription = getSubscription(email, category);

		if (subscription == null) {
			subscription = new Subscription();
			subscription.setEmail(email);
			subscription.setCategory(category);
			subscription.setInterval(interval);
			subscription.setConfirmKey(StringTools.randomUUID());
			subscription.setConfirmed(false);
			savaOrUpdate(subscription);

			try {
				sendConfirmEmail(subscription);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}

		} else {
			subscription.setInterval(interval);
			savaOrUpdate(subscription);
		}
		return subscription;
	}

	private void sendConfirmEmail(Subscription subscription) throws IOException, TemplateException {
		String subjectTemplate = templates.get(SUBSCRIPTION_CONFIRM_MAIL_SUBJECT);
		String subject = FreemarkerTools.process(subjectTemplate, new HashMap<String, Object>());
		Map<String, Object> rootMap = new HashMap<String, Object>();
		rootMap.put("subscription", subscription);
		String contentTemplate = templates.get(SUBSCRIPTION_CONFIRM_MAIL_CONTENT);
		String content = FreemarkerTools.process(contentTemplate, rootMap);
		mailSender.sendMail(new String[] { subscription.getEmail() }, null, subject, content);
	}

	public void setMailSender(SpringMailSender mailSender) {
		this.mailSender = mailSender;
	}

	public void setTemplates(Map<String, String> templates) {
		this.templates = templates;
	}

}
